﻿using Log.Recorder.Entity;
using Newtonsoft.Json;
using System;

namespace Log.Recorder
{
    /// <summary>
    /// 日志记录器
    /// </summary>
    public class LogRecorder : IDisposable
    {
        public static LogRecorder Instance => new LogRecorder();

        /// <summary>
        /// 堆栈踪迹层数
        /// </summary>
        private int stackTraceLayer { get; set; }

        public LogRecorder() {
            stackTraceLayer = 4;
        }
        /// <summary>
        /// 堆栈踪迹层数 （大于 3）
        /// </summary>
        /// <param name="stackTraceLayer"></param>
        public LogRecorder(int stackTraceLayer)
        {
            this.stackTraceLayer = stackTraceLayer;
        }



        /// <summary>
        /// 配置信息
        /// </summary>
        public static LogConfigInfo ConfigInfo
        {
            get {
                return LogConfig.ConfigInfo;
            }
        }

        /// <summary>
        /// 记录异常日志
        /// </summary>
        /// <param name="message">消息</param>
        /// <param name="data">数据</param>
        /// <param name="logType">类型</param>
        public void Error(string message, object data = null, string logType = null) {
            using (InternalLogRecorder ilog = new InternalLogRecorder(stackTraceLayer)) {
                ilog.DoRecord(LogLevel.Error, message, data, logType, null);
            } 
        }
        /// <summary>
        /// 记录跟踪或信息日志
        /// </summary>
        /// <param name="message">消息</param>
        /// <param name="data">数据</param>
        /// <param name="logType">类型</param>
        public void Trace(string message, object data = null, string logType = null)
        {
            using (InternalLogRecorder ilog = new InternalLogRecorder(stackTraceLayer))
            {
                ilog.DoRecord(LogLevel.Trace, message, data, logType, null);
            }
        }
        /// <summary>
        /// 记录调试日志
        /// </summary>
        /// <param name="message">消息</param>
        /// <param name="data">数据</param>
        /// <param name="logType">类型</param>
        public void Debug(string message, object data = null, string logType = null)
        {
            using (InternalLogRecorder ilog = new InternalLogRecorder(stackTraceLayer))
            {
                ilog.DoRecord(LogLevel.Debug, message, data, logType, null);
            }
        }
        /// <summary>
        /// 记录其他日志
        /// </summary>
        /// <param name="fileName">日志文件名</param>
        /// <param name="message">消息</param>
        /// <param name="data">数据</param>
        /// <param name="logType">类型</param>
        public void Other(string fileName, string message, object data = null, string logType = null)
        {
            using (InternalLogRecorder ilog = new InternalLogRecorder(stackTraceLayer))
            {
                ilog.DoRecord(LogLevel.Other, message, data, logType, fileName);
            }
        }

        /// <summary>
        /// 日志器池大小
        /// </summary>
        public static int WriterCount
        {
            get { return DbWriterPool.WriterCount; }
        }

        #region 释放资源

        private bool disposedValue;
        public void Dispose()
        {
            if (!disposedValue)
            {
                
                // TODO: 释放未托管的资源(未托管的对象)并重写终结器
                // TODO: 将大型字段设置为 null

                /*
                 托管对象指的是.net可以自动进行回收的资源，主要是指托管对象在堆上分配的内存资源。
                托管资源的回收工作是不需要人工干预的，有.net运行库在合适的时间进行回收。（手动回收GC.Collect）

                 非托管对象指.net不知道如何回收的资源，最常见的一类非托管资源是包装操作系统资源的对象，
                例如文件、窗口、网络连接、数据库连接、画刷、图标等。这类资源，垃圾回收器在清理的时候会调用Object.Finalize()方法。
                默认情况下，方法是空的，对于非托管对象在此方法中需要编写回收非托管对象的代码，以便垃圾回收器正确回收。(例如我们
                通常打开文件、图片等后需要进行Close()或者Dispose()去释放)。

                 */

                disposedValue = true;
            }
        }

        #endregion

    }
}
